location of cities and travel routes
set.seed(7)
setCities <- function(n.cities, mesh = seq(0,1,1e-4)){
cities <- data.frame(id = 1:n.cities,
x = sample(mesh, n.cities),
y = sample(mesh, n.cities))
cities[1, ] <- data.frame(1,0,0)
invisible(cities)
}
(cities <- setCities(10))
## id x y
## 1 1 0.0000 0.0000
## 2 2 0.3977 0.2314
## 3 3 0.1156 0.7727
## 4 4 0.0697 0.0962
## 5 5 0.2436 0.4533
## 6 6 0.7916 0.0846
## 7 7 0.3398 0.5603
## 8 8 0.9714 0.0086
## 9 9 0.1657 0.9850
## 10 10 0.4587 0.3163
# start from id=1
travel <- data.frame(id = c(1, sample(2:NROW(cities)))) %>%
left_join(cities, by="id")
travel <- rbind(travel, travel[1, ])
## calculate total trip.
total.distance <- foreach(i=1:NROW(cities), .combine = sum) %do%({
from <- travel[i, ]
to <- travel[i+1, ]
distance <- ((from$x - to$x)^2 + (from$y - to$y)^2)^0.5
return(distance)
})
total.distance
## [1] 6.012823
# plot travelling orders
plot(y~x, travel[-1,], cex=1.5,
main = sprintf("total trip = %f", total.distance))
points(y~x, data=travel[1,], pch=16, col="red", cex=1.5)
for(i in 1:NROW(cities)){
from <- travel[i, ]
to <- travel[i+1, ]
arrows(x0 = from$x, y0 = from$y, x1 = to$x, y1=to$y, col="blue",
length = 0.1, angle = 20)
}

individual
individual <- function(.cities){
c(1, sample(2:NROW(.cities)))
}
# example
x1 <- individual(cities)
paste0(x1, collapse = "-")
## [1] "1-5-7-3-8-2-9-4-6-10"
# get total distance
fitness <- function(trip, cities){
stopifnot(length(trip) == NROW(cities))
travel <- data.frame(id = trip) %>%
left_join(cities, by="id")
travel <- rbind(travel, travel[1, ])
total.distance <- foreach(i=1:NROW(cities), .combine = sum) %do%({
from <- travel[i, ]
to <- travel[i+1, ]
distance <- ((from$x - to$x)^2 + (from$y - to$y)^2)^0.5
return(distance)
})
return(total.distance)
}
# example
x1 <- individual(cities)
fitness(x1, cities)
## [1] 6.214204
# order crossover
crossover <- function(p1, p2, show.pos = FALSE){
len_chrom <- length(p1)
stopifnot(len_chrom >= 3,
len_chrom == length(p2))
# position at crossover
at <- sample(2:(length(p1)-1),2)
at <- sort(at)
child <- rep(NA, length(p1))
child[1] <- 1
child[at[1]:at[2]] <- p1[at[1]:at[2]]
chid.inherit <- child
p2.rot <- p2[c((at[2]+1):length(p2),1:(at[2]))]
child.omit <- setdiff(p2, child)
child[which(is.na(child))] <- child.omit
if(show.pos){
child <- list(at = at, p1 = p1, p2 = p2,
p1.inherit = chid.inherit, p2.rotated = p2.rot,
p2.omitted = child.omit, new.chrom = child)
}
return(child)
}
# example
chr1 <- individual(cities)
chr2 <- individual(cities)
crossover(chr1, chr2)
## [1] 1 3 10 4 5 7 6 9 2 8
crossover(chr1, chr2, show.pos = TRUE)
## $at
## [1] 4 5
##
## $p1
## [1] 1 9 10 8 5 7 6 3 4 2
##
## $p2
## [1] 1 3 10 4 9 2 8 5 7 6
##
## $p1.inherit
## [1] 1 NA NA 8 5 NA NA NA NA NA
##
## $p2.rotated
## [1] 2 8 5 7 6 1 3 10 4 9
##
## $p2.omitted
## [1] 3 10 4 9 2 7 6
##
## $new.chrom
## [1] 1 3 10 8 5 4 9 2 7 6
# mutation (inversion)
mutation <- function(chrom, mutate.prob =0.05, show.pos = FALSE){
stopifnot(length(chrom)>3)
for(i in 2:length(chrom)){
if(runif(1) < mutate.prob){
base <- setdiff(2:length(chrom), i)
at <- c(i, sample(base, 1))
if(show.pos == TRUE){
cat(sprintf("%i <=> %i \n", at[1], at[2]))
}
chrom[at] <- chrom[rev(at)]
}
}
return(chrom)
}
# example
mutation(1:10, mutate.prob = 0.3, show.pos = TRUE)
## 3 <=> 7
## 6 <=> 7
## [1] 1 2 7 4 5 3 6 8 9 10
population
printChroms <- function(l){
sapply(l, paste0, collapse = "-") %>% tibble()
}
POP_SIZE = 10 # population size
N_ELITE = 2 # number of elite individual for next chromration
MUTATE_PROB = 0.05 # mutation rate
print(factorial(NROW(cities))) > POP_SIZE
## [1] 3628800
## [1] TRUE
chrom <- NULL
while(length(chrom) < POP_SIZE){
new.ind <- individual(cities)
# print(length(chrom))
germ <- paste0(new.ind, collapse = "-")
if(! germ %in% chrom){
chrom <- c(chrom, list(new.ind))
}
}
population <- tibble(chrom = chrom)
printChroms(population$chrom)
## # A tibble: 10 x 1
## .
## <chr>
## 1 1-9-10-3-6-8-2-5-7-4
## 2 1-5-4-2-7-8-9-3-10-6
## 3 1-9-3-4-8-7-10-5-2-6
## 4 1-2-8-3-6-9-10-4-7-5
## 5 1-7-8-3-6-4-9-5-2-10
## 6 1-4-8-3-5-2-7-10-9-6
## 7 1-9-7-8-6-5-10-4-3-2
## 8 1-7-4-10-3-6-2-9-5-8
## 9 1-3-10-4-6-8-5-7-9-2
## 10 1-9-6-10-5-4-3-8-2-7
population$fits <- sapply(population$chrom, fitness, cities)
population %<>% arrange(fits)
# Preserve elite individuals
nextInd.elite <- population %>% head(N_ELITE)
nextInd.elite %>% head %>% print()
## # A tibble: 2 x 2
## chrom fits
## <list> <dbl>
## 1 <dbl [10]> 5.14
## 2 <dbl [10]> 5.42
# Generate children via: selection -> crossover -> mutation
#
pf <- population$fits
roulette.pie <- (max(pf) -pf) / (max(pf) - min(pf))
roulette.pie <- roulette.pie / sum(roulette.pie)
roulette.pie %>% tibble()
## # A tibble: 10 x 1
## .
## <dbl>
## 1 0.221
## 2 0.183
## 3 0.158
## 4 0.151
## 5 0.145
## 6 0.101
## 7 0.0224
## 8 0.0123
## 9 0.00750
## 10 0
pie(roulette.pie, clockwise = TRUE,
main = "roulette based on fitness")

roulette.thr <- cumsum(roulette.pie)
roulette.thr %>% tibble()
## # A tibble: 10 x 1
## .
## <dbl>
## 1 0.221
## 2 0.404
## 3 0.561
## 4 0.712
## 5 0.857
## 6 0.958
## 7 0.980
## 8 0.992
## 9 1.000
## 10 1.000
which(roulette.thr > print(x <- runif(1)))[1]
## [1] 0.3776336
## [1] 2
which(roulette.thr > 0.999)[1]
## [1] 9
#
# selection -> crossover
chrom <- NULL
while(length(chrom) < NROW(population)- NROW(nextInd.elite)){
p1 <- which(roulette.thr > runif(1))[1]
p2 <- which(roulette.thr > runif(1))[1]
while(p1 == p2){
p2 <- which(roulette.thr > runif(1))[1]
}
new.ind <- crossover(population$chrom[p1] %>% unlist,
population$chrom[p2] %>% unlist)
germ <- paste0(new.ind, collapse = "-")
if(! germ %in% chrom){
chrom <- c(chrom, list(new.ind))
}
}
printChroms(chrom)
## # A tibble: 8 x 1
## .
## <chr>
## 1 1-3-10-2-7-8-9-4-6-5
## 2 1-10-3-6-7-8-9-2-5-4
## 3 1-4-6-10-8-3-5-2-7-9
## 4 1-5-4-8-9-2-7-3-10-6
## 5 1-5-10-3-4-2-7-8-9-6
## 6 1-5-4-2-7-8-9-3-10-6
## 7 1-8-7-9-6-5-10-4-3-2
## 8 1-9-3-4-8-10-5-7-2-6
# mutation
nextInd.gen <- tibble(
chrom = lapply(chrom, mutation, mutate.prob = MUTATE_PROB))
all.equal(chrom, nextInd.gen$chrom)
## [1] "Component 1: Mean relative difference: 0.1176471"
## [2] "Component 6: Mean relative difference: 0.4"
cbind(chrom = printChroms(chrom), nextInd = printChroms(nextInd.gen$chrom))
## . .
## 1 1-3-10-2-7-8-9-4-6-5 1-3-10-2-7-9-8-4-6-5
## 2 1-10-3-6-7-8-9-2-5-4 1-10-3-6-7-8-9-2-5-4
## 3 1-4-6-10-8-3-5-2-7-9 1-4-6-10-8-3-5-2-7-9
## 4 1-5-4-8-9-2-7-3-10-6 1-5-4-8-9-2-7-3-10-6
## 5 1-5-10-3-4-2-7-8-9-6 1-5-10-3-4-2-7-8-9-6
## 6 1-5-4-2-7-8-9-3-10-6 1-5-4-3-7-8-9-2-10-6
## 7 1-8-7-9-6-5-10-4-3-2 1-8-7-9-6-5-10-4-3-2
## 8 1-9-3-4-8-10-5-7-2-6 1-9-3-4-8-10-5-7-2-6
population <- bind_rows(nextInd.elite, nextInd.gen)
population$fits <- sapply(population$chrom, fitness, cities)
population %<>% arrange(fits)
population
## # A tibble: 10 x 2
## chrom fits
## <list> <dbl>
## 1 <dbl [10]> 5.14
## 2 <dbl [10]> 5.35
## 3 <dbl [10]> 5.40
## 4 <dbl [10]> 5.42
## 5 <dbl [10]> 6.10
## 6 <dbl [10]> 6.29
## 7 <dbl [10]> 6.32
## 8 <dbl [10]> 6.43
## 9 <dbl [10]> 6.48
## 10 <dbl [10]> 6.70
popuration function
initPopulation <- function(pop.size, .cities){
stopifnot(factorial(NROW(.cities)) > pop.size)
chrom <- NULL
while(length(chrom) < pop.size){
new.ind <- individual(.cities)
# print(length(chrom))
germ <- paste0(new.ind, collapse = "-")
if(! germ %in% chrom){
chrom <- c(chrom, list(new.ind))
}
}
population <- tibble(chrom = chrom)
population$fits <- sapply(population$chrom, fitness, .cities)
return(population %>% arrange(fits))
}
# example
pop <- initPopulation(20, cities)
printChroms(pop$chrom)
## # A tibble: 20 x 1
## .
## <chr>
## 1 1-10-5-2-6-8-9-3-7-4
## 2 1-4-2-8-7-6-10-5-3-9
## 3 1-2-3-9-4-10-7-5-8-6
## 4 1-5-3-4-8-6-7-9-2-10
## 5 1-5-8-4-2-6-7-3-9-10
## 6 1-10-3-5-4-7-2-8-6-9
## 7 1-10-7-6-8-3-4-2-5-9
## 8 1-8-6-4-9-2-5-3-10-7
## 9 1-9-2-7-3-6-8-4-10-5
## 10 1-3-5-2-8-4-9-7-10-6
## 11 1-4-9-6-2-7-3-10-5-8
## 12 1-5-7-2-3-8-10-6-9-4
## 13 1-4-2-8-9-10-7-5-6-3
## 14 1-6-3-9-2-5-8-4-10-7
## 15 1-6-3-5-7-8-4-10-2-9
## 16 1-7-3-6-9-4-10-2-8-5
## 17 1-8-7-2-10-4-3-5-6-9
## 18 1-3-10-4-9-5-8-2-7-6
## 19 1-9-10-7-8-4-3-6-5-2
## 20 1-2-5-6-3-8-7-10-4-9
alternate <- function(population, .cities, elite.size, mutate.prob = 0.3){
stopifnot(!missing(population), !missing(.cities),
NROW(population) > elite.size )
# Preserve elite individuals
nextInd.elite <- population %>%
arrange(fits) %>%
head(elite.size)
# Generate children via: selection -> crossover -> mutation
# roulette source based on fitness for selection
pf <- population$fits
roulette.pie <- (max(pf) -pf) / (max(pf) - min(pf))
roulette.pie <- roulette.pie / sum(roulette.pie)
roulette.thr <- cumsum(roulette.pie)
# selection -> crossover
chrom <- NULL
while(length(chrom) < NROW(population) - NROW(nextInd.elite)){
p1 <- which(roulette.thr > runif(1))[1]
p2 <- which(roulette.thr > runif(1))[1]
while(p1 == p2){
p2 <- which(roulette.thr > runif(1))[1]
}
new.ind <- crossover(population$chrom[p1] %>% unlist,
population$chrom[p2] %>% unlist)
germ <- paste0(new.ind, collapse = "-")
if(! germ %in% chrom){
chrom <- c(chrom, list(new.ind))
}
}
# mutation
nextInd.gen <- tibble(
chrom = lapply(chrom, mutation, mutate.prob = mutate.prob))
population <- bind_rows(nextInd.elite, nextInd.gen)
population$fits <- sapply(population$chrom, fitness, .cities)
return(population %>% arrange(fits))
}
# example
(pop <- initPopulation(30, cities))
## # A tibble: 30 x 2
## chrom fits
## <list> <dbl>
## 1 <dbl [10]> 4.65
## 2 <dbl [10]> 4.77
## 3 <dbl [10]> 5.12
## 4 <dbl [10]> 5.16
## 5 <dbl [10]> 5.17
## 6 <dbl [10]> 5.17
## 7 <dbl [10]> 5.20
## 8 <dbl [10]> 5.38
## 9 <dbl [10]> 5.48
## 10 <dbl [10]> 5.50
## # ... with 20 more rows
(pop.new <- alternate(pop, cities, elite.size = 3, mutate.prob = 0.8))
## # A tibble: 30 x 2
## chrom fits
## <list> <dbl>
## 1 <dbl [10]> 4.54
## 2 <dbl [10]> 4.65
## 3 <dbl [10]> 4.76
## 4 <dbl [10]> 4.77
## 5 <dbl [10]> 4.81
## 6 <dbl [10]> 5.12
## 7 <dbl [10]> 5.27
## 8 <dbl [10]> 5.27
## 9 <dbl [10]> 5.37
## 10 <dbl [10]> 5.48
## # ... with 20 more rows
plot.trip <- function(trip, .cities){
stopifnot(!missing(trip),
!missing(.cities),
NROW(.cities) == length(trip))
travel <- data.frame(id = trip) %>%
left_join(.cities, by="id")
travel <- rbind(travel, travel[1, ])
# print(trip)
# print(travel)
total.distance <- fitness(trip, .cities)
# print(total.distance)
# plot travelling orders
plot(y~x, travel[-1,], cex=1.5,
main = sprintf("total trip = %f", total.distance))
points(y~x, data=travel[1, ], pch=16, col="red", cex=1.5)
for(i in 1:NROW(.cities)){
from <- travel[i, ]
to <- travel[i+1, ]
arrows(x0 = from$x, y0 = from$y, x1 = to$x, y1=to$y, col="blue",
length = 0.1, angle = 20)
}
}
# example
sample.trip <- individual(cities)
fitness(sample.trip, cities)
## [1] 4.634169
plot.trip(sample.trip, cities)

example 1
exec
set.seed(7)
N_CITIES = 10 # number of cities to travel
GEN_MAX = 15 # number of generation
POP_SIZE = 50 # population size
N_ELITE = 3 # number of elite individual for next chromration
MUTATE_PROB = 0.1# mutation rate
factorial(N_CITIES)
## [1] 3628800
start_time <- Sys.time()
(cities <- setCities(N_CITIES))
sample.trip <- individual(cities)
plot.trip(sample.trip, cities)

generation <- list(NULL)
(pop <- initPopulation(POP_SIZE, cities))
for(i in 1:GEN_MAX){
print(i)
generation[[i]] <- pop
pop <- alternate(pop, cities,
elite.size = N_ELITE,
mutate.prob = MUTATE_PROB)
}
Sys.time() - start_time
eval
top1 <- NULL
for(i in 1:length(generation)){
this <- generation[[i]]
top1 <- rbind(top1, tibble(gen=i,
chrom = this$chrom[1],
fits = this$fits[1]))
}
top1
## # A tibble: 50 x 3
## gen chrom fits
## <int> <list> <dbl>
## 1 1 <dbl [10]> 4.71
## 2 2 <dbl [10]> 4.41
## 3 3 <dbl [10]> 4.41
## 4 4 <dbl [10]> 4.07
## 5 5 <dbl [10]> 4.01
## 6 6 <dbl [10]> 4.01
## 7 7 <dbl [10]> 4.01
## 8 8 <dbl [10]> 4.01
## 9 9 <dbl [10]> 3.64
## 10 10 <dbl [10]> 3.64
## # ... with 40 more rows
plot
library(animation)
saveGIF({
for(g in 1:length(generation)){
par(mfrow = c(1,2))
this.trip <- unlist(top1$chrom[g])
plot.trip(this.trip, cities)
plot(fits~gen, top1, type="b",
main = sprintf("generation = %i (fits = %f)", g, top1$fits[g]))
points(x=g, y=top1$fits[g], pch=16, col="red", cex=1.5)
# top1;max(Y)
par(mfrow = c(1,1))
}
}, movie.name = "./output/stepGA_10cities-50steps.gif",
interval = 1, ani.width=960, ani.height=480)

example 2 (large ver.)
exec
set.seed(1)
N_CITIES = 20 # number of cities to travel
GEN_MAX = 350 # number of generation
POP_SIZE = 150 # population size
N_ELITE = 5 # number of elite individual for next chromration
MUTATE_PROB = 0.05 # mutation rate
factorial(N_CITIES)
## [1] 2.432902e+18
start_time <- Sys.time()
(cities.L <- setCities(N_CITIES))
generation.L <- list(NULL)
(pop <- initPopulation(POP_SIZE, cities.L))
for(i in 1:GEN_MAX){
print(i)
generation.L[[i]] <- pop
pop <- alternate(pop, cities.L,
elite.size = N_ELITE,
mutate.prob = MUTATE_PROB)
}
Sys.time() - start_time
eval & plot
top1.L <- NULL
for(i in 1:length(generation.L)){
this <- generation.L[[i]]
top1.L <- rbind(top1.L, tibble(gen=i,
chrom = this$chrom[1],
fits = this$fits[1]))
}
saveGIF({
for(g in 1:length(generation.L)){
par(mfrow = c(1,2))
this.trip <- unlist(top1.L$chrom[g])
plot.trip(this.trip, cities.L)
plot(fits~gen, top1.L, type="b",
main = sprintf("generation = %i (fits = %f)", g, top1.L$fits[g]))
points(x=g, y=top1.L$fits[g], pch=16, col="red", cex=1.5)
# top1;max(Y)
par(mfrow = c(1,1))
}
}, movie.name = "./output/stepGA_20cities.gif",
interval = 0.1, ani.width=960, ani.height=480)
## Executing:
## "convert -loop 0 -delay 10 Rplot1.png Rplot2.png Rplot3.png
## Rplot4.png Rplot5.png Rplot6.png Rplot7.png Rplot8.png
## Rplot9.png Rplot10.png Rplot11.png Rplot12.png Rplot13.png
## Rplot14.png Rplot15.png Rplot16.png Rplot17.png Rplot18.png
## Rplot19.png Rplot20.png Rplot21.png Rplot22.png Rplot23.png
## Rplot24.png Rplot25.png Rplot26.png Rplot27.png Rplot28.png
## Rplot29.png Rplot30.png Rplot31.png Rplot32.png Rplot33.png
## Rplot34.png Rplot35.png Rplot36.png Rplot37.png Rplot38.png
## Rplot39.png Rplot40.png Rplot41.png Rplot42.png Rplot43.png
## Rplot44.png Rplot45.png Rplot46.png Rplot47.png Rplot48.png
## Rplot49.png Rplot50.png Rplot51.png Rplot52.png Rplot53.png
## Rplot54.png Rplot55.png Rplot56.png Rplot57.png Rplot58.png
## Rplot59.png Rplot60.png Rplot61.png Rplot62.png Rplot63.png
## Rplot64.png Rplot65.png Rplot66.png Rplot67.png Rplot68.png
## Rplot69.png Rplot70.png Rplot71.png Rplot72.png Rplot73.png
## Rplot74.png Rplot75.png Rplot76.png Rplot77.png Rplot78.png
## Rplot79.png Rplot80.png Rplot81.png Rplot82.png Rplot83.png
## Rplot84.png Rplot85.png Rplot86.png Rplot87.png Rplot88.png
## Rplot89.png Rplot90.png Rplot91.png Rplot92.png Rplot93.png
## Rplot94.png Rplot95.png Rplot96.png Rplot97.png Rplot98.png
## Rplot99.png Rplot100.png Rplot101.png Rplot102.png
## Rplot103.png Rplot104.png Rplot105.png Rplot106.png
## Rplot107.png Rplot108.png Rplot109.png Rplot110.png
## Rplot111.png Rplot112.png Rplot113.png Rplot114.png
## Rplot115.png Rplot116.png Rplot117.png Rplot118.png
## Rplot119.png Rplot120.png Rplot121.png Rplot122.png
## Rplot123.png Rplot124.png Rplot125.png Rplot126.png
## Rplot127.png Rplot128.png Rplot129.png Rplot130.png
## Rplot131.png Rplot132.png Rplot133.png Rplot134.png
## Rplot135.png Rplot136.png Rplot137.png Rplot138.png
## Rplot139.png Rplot140.png Rplot141.png Rplot142.png
## Rplot143.png Rplot144.png Rplot145.png Rplot146.png
## Rplot147.png Rplot148.png Rplot149.png Rplot150.png
## Rplot151.png Rplot152.png Rplot153.png Rplot154.png
## Rplot155.png Rplot156.png Rplot157.png Rplot158.png
## Rplot159.png Rplot160.png Rplot161.png Rplot162.png
## Rplot163.png Rplot164.png Rplot165.png Rplot166.png
## Rplot167.png Rplot168.png Rplot169.png Rplot170.png
## Rplot171.png Rplot172.png Rplot173.png Rplot174.png
## Rplot175.png Rplot176.png Rplot177.png Rplot178.png
## Rplot179.png Rplot180.png Rplot181.png Rplot182.png
## Rplot183.png Rplot184.png Rplot185.png Rplot186.png
## Rplot187.png Rplot188.png Rplot189.png Rplot190.png
## Rplot191.png Rplot192.png Rplot193.png Rplot194.png
## Rplot195.png Rplot196.png Rplot197.png Rplot198.png
## Rplot199.png Rplot200.png Rplot201.png Rplot202.png
## Rplot203.png Rplot204.png Rplot205.png Rplot206.png
## Rplot207.png Rplot208.png Rplot209.png Rplot210.png
## Rplot211.png Rplot212.png Rplot213.png Rplot214.png
## Rplot215.png Rplot216.png Rplot217.png Rplot218.png
## Rplot219.png Rplot220.png Rplot221.png Rplot222.png
## Rplot223.png Rplot224.png Rplot225.png Rplot226.png
## Rplot227.png Rplot228.png Rplot229.png Rplot230.png
## Rplot231.png Rplot232.png Rplot233.png Rplot234.png
## Rplot235.png Rplot236.png Rplot237.png Rplot238.png
## Rplot239.png Rplot240.png Rplot241.png Rplot242.png
## Rplot243.png Rplot244.png Rplot245.png Rplot246.png
## Rplot247.png Rplot248.png Rplot249.png Rplot250.png
## Rplot251.png Rplot252.png Rplot253.png Rplot254.png
## Rplot255.png Rplot256.png Rplot257.png Rplot258.png
## Rplot259.png Rplot260.png Rplot261.png Rplot262.png
## Rplot263.png Rplot264.png Rplot265.png Rplot266.png
## Rplot267.png Rplot268.png Rplot269.png Rplot270.png
## Rplot271.png Rplot272.png Rplot273.png Rplot274.png
## Rplot275.png Rplot276.png Rplot277.png Rplot278.png
## Rplot279.png Rplot280.png Rplot281.png Rplot282.png
## Rplot283.png Rplot284.png Rplot285.png Rplot286.png
## Rplot287.png Rplot288.png Rplot289.png Rplot290.png
## Rplot291.png Rplot292.png Rplot293.png Rplot294.png
## Rplot295.png Rplot296.png Rplot297.png Rplot298.png
## Rplot299.png Rplot300.png Rplot301.png Rplot302.png
## Rplot303.png Rplot304.png Rplot305.png Rplot306.png
## Rplot307.png Rplot308.png Rplot309.png Rplot310.png
## Rplot311.png Rplot312.png Rplot313.png Rplot314.png
## Rplot315.png Rplot316.png Rplot317.png Rplot318.png
## Rplot319.png Rplot320.png Rplot321.png Rplot322.png
## Rplot323.png Rplot324.png Rplot325.png Rplot326.png
## Rplot327.png Rplot328.png Rplot329.png Rplot330.png
## Rplot331.png Rplot332.png Rplot333.png Rplot334.png
## Rplot335.png Rplot336.png Rplot337.png Rplot338.png
## Rplot339.png Rplot340.png Rplot341.png Rplot342.png
## Rplot343.png Rplot344.png Rplot345.png Rplot346.png
## Rplot347.png Rplot348.png Rplot349.png Rplot350.png
## "stepGA_20cities.gif""
## Output at: ./output/stepGA_20cities.gif
## [1] TRUE
